! Li Dong <dongli@lasg.iap.ac.cn>
!
! - 2024-03-24: Initial creation.

module adv_2d_common_mod

  use netcdf

  implicit none

  real, parameter :: pi = atan(1.0d0) * 4.0d0

  integer :: time_step = 0, old = 1, new = 2
  character(256) namelist_path
  logical is_exist

contains

  subroutine advance_time()

    integer tmp

    ! Change time indices.
    tmp = old; old = new; new = tmp
    time_step = time_step + 1

  end subroutine advance_time

  subroutine apply_bc(ns, nx, ny, f)

    integer, intent(in) :: ns
    integer, intent(in) :: nx
    integer, intent(in) :: ny
    real, intent(inout) :: f(1-ns:nx+ns,1-ns:ny+ns)

    integer i, j

    do j = 1, ny
      do i = 1, ns
        f(1-ns+i-1,j) = f(nx-ns+i,j)
        f(nx+i,j) = f(i,j)
      end do
    end do
    do j = 1, ns
      do i = 1, nx
        f(i,1-ns+j-1) = f(i,ny-ns+j)
        f(i,ny+j) = f(i,j)
      end do
    end do
    ! Left-top corner.
    do j = 1, ns
      do i = 1, ns
        f(1-ns+i-1,1-ns+j-1) = f(nx-ns+i,ny-ns+j)
      end do
    end do
    ! Right-top corner.
    do j = 1, ns
      do i = 1, ns
        f(nx+i,1-ns+j-1) = f(i,ny-ns+j)
      end do
    end do
    ! Left-bottom corner.
    do j = 1, ns
      do i = 1, ns
        f(1-ns+i-1,ny+j) = f(nx-ns+i,j)
      end do
    end do
    ! Right-bottom corner.
    do j = 1, ns
      do i = 1, ns
        f(nx+i,ny+j) = f(i,j)
      end do
    end do

  end subroutine apply_bc

  subroutine output(scheme, time_step, ns, nx, ny, x, y, rho)

    character(*), intent(in) :: scheme
    integer, intent(in) :: time_step
    integer, intent(in) :: ns
    integer, intent(in) :: nx
    integer, intent(in) :: ny
    real, intent(in) :: x  (1-ns:nx+ns)
    real, intent(in) :: y  (1-ns:ny+ns)
    real, intent(in) :: rho(1-ns:nx+ns,1-ns:ny+ns)

    character(256) file_name
    integer ncid, time_dimid, time_varid, x_dimid, x_varid, y_dimid, y_varid, rho_varid, ierr

    write(file_name, "(A, '.', I3.3, 'x', I3.3, '.', I4.4, '.nc')") trim(scheme), nx, ny, time_step

    ierr = NF90_CREATE(file_name, NF90_CLOBBER, ncid)
    ierr = NF90_PUT_ATT(ncid, NF90_GLOBAL, 'scheme', trim(scheme))

    ierr = NF90_DEF_DIM(ncid, 'time', NF90_UNLIMITED, time_dimid)
    ierr = NF90_DEF_VAR(ncid, 'time', NF90_INT, [time_dimid], time_varid)
    ierr = NF90_DEF_DIM(ncid, 'x', nx, x_dimid)
    ierr = NF90_DEF_VAR(ncid, 'x', NF90_FLOAT, [x_dimid], x_varid)
    ierr = NF90_DEF_DIM(ncid, 'y', ny, y_dimid)
    ierr = NF90_DEF_VAR(ncid, 'y', NF90_FLOAT, [y_dimid], y_varid)
    ierr = NF90_DEF_VAR(ncid, 'rho', NF90_FLOAT, [x_dimid, y_dimid, time_dimid], rho_varid)

    ierr = NF90_ENDDEF(ncid)

    ierr = NF90_PUT_VAR(ncid, time_varid, time_step)
    ierr = NF90_PUT_VAR(ncid, x_varid, x(1:nx))
    ierr = NF90_PUT_VAR(ncid, y_varid, y(1:ny))
    ierr = NF90_PUT_VAR(ncid, rho_varid, rho(1:nx,1:ny))

    ierr = NF90_CLOSE(ncid)

  end subroutine output

end module adv_2d_common_mod